#include <GameEngine/Maps/map.h>

#ifdef GAMEENGINE_NAMESPACES
namespace GameEngine {
#endif


//=================================================================================


//! Constructor
/*!
 @param width The width of the square map
 @param height The height of the square map
 */
Map::Map(MapSize width, MapSize height) :
	width_(width), height_(height),
	map_box_( Point2d<float>(0,0), Vector2d<float>(1,0), Vector2d<float>(0,1) )
{}

//! Destructor
Map::~Map() {}

//! Accessor to the width of the map (read only)
/*!
 @return The width of the map
 */
Map::MapSize Map::width() const {
	return width_;
}

//! Accessor to the height of the map (read only)
/*!
 @return The height of the map
 */
Map::MapSize Map::height() const {
	return height_;
}

//! Accessor to the bounding box of the map (read-write)
/*!
 @return A reference to the bounding box of the map
 */
Parallelogram2d<float>& Map::map_box() {
	return map_box_;
}

//! Accessor to the bounding box of the map (read only)
/*!
 @return A constant reference to the bounding box of the map
 */
const Parallelogram2d<float>& Map::map_box() const {
	return map_box_;
}

//! Accessor to the terrains associated to the map (read-write)
/*!
 @return A reference to the terrains associated to the map
 */
TerrainManager& Map::terrains() {
	return terrains_;
}

//! Accessor to the terrains associated to the map (read only)
/*!
 @return A constant reference to the terrains associated to the map
 */
const TerrainManager& Map::terrains() const {
	return terrains_;
}

//! Convert a point from global coordinates to map coordinates
/*!
 @param rhs 2D coordinates specified in the world coordinate system
 @return The point coordinates specified in the local map coordinate system
 */
Point2d<float> Map::global_to_local_coordinates(const Point2d<float>& rhs) const {
	Coords2d<float> tmp = map_box_.coordinates(rhs);
	return Point2d<float>(tmp.u(),tmp.v());
}

//! Convert a point from local map coordinates to global coordinates
/*!
 @param rhs 2D coordinates specified in the local map coordinate system
 @return The point coordinates specified in the world coordinate system
 */
Point2d<float> Map::local_to_global_coordinates(const Point2d<float>& rhs) const {
	return map_box_.point( Coords2d<float>(rhs.x(),rhs.y()) );
}

//! Compute the index in the cell array from the input cell coordinates
/*!
 @param x The x index of the cell (width axis)
 @param y The y index of the cell (height axis)
 @return The corresponding index in the cell array
 */
Map::CellIndex Map::get_array_index(MapIndex x, MapIndex y) const {
	return x+y*width_;
}

//! Compute the axes indexes from the input cell coordinates in the cell array
/*!
 @param x The returned x index of the cell (width axis)
 @param y The returned y index of the cell (height axis)
 @param index The input cell coordinates in the cell array
 @return True if map indexes were correctly computed, false otherwise
 */
bool Map::get_axes_indexes(MapIndex& x, MapIndex& y, CellIndex index) const {
	if ( index >= (width_*height_) ) return false;
	x = index % width_;
	y = ( index - x ) / width_;
	return true;
}


//=================================================================================


#ifdef GAMEENGINE_NAMESPACES
} // namespace GameEngine
#endif
